﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.VisualStudio.Samples;
using System.IO;
using Microsoft.VisualStudio.IntelliTrace;

namespace UofCASE.AgileProductLinerDSL.Nant.Tasks
{
    class MethodCallEventHandler : ThreadChainHandler, IDisposable
    {
        private System.IO.FileInfo resultFile;
        private TextWriter Writer { get; set; }
        private StringBuilder Tabs;

        public MethodCallEventHandler(System.IO.FileInfo resultFile)
        {
            this.resultFile = resultFile;
            Writer = new StreamWriter(resultFile.FullName, false, Encoding.UTF8, 2048);
            Writer.WriteLine("<Calls>");
            Tabs = new StringBuilder("\t");
        }
        public Microsoft.VisualStudio.IntelliTrace.IntelliTraceProcess Process
        {
            set;
            get;
        }

        public void MethodEnterEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
            ResolvedMethodEnterEvent Event = (ResolvedMethodEnterEvent)ev;
            
            StringBuilder buff = new StringBuilder(Tabs.ToString());
            buff.Append("<Call ");
            buff.Append("class").Append("=\"").Append(Event.Method.ContainingTypeName).Append("\" ");
            buff.Append("method").Append("=\"").Append(Event.Method.MethodName).Append("\" ");
            buff.Append("returnType").Append("=\"").Append(Event.Method.ReturnTypeName).Append("\" ");
            buff.Append(">");
            IList<IDataElement> parameters = Event.GetParameters();
            for (int i = 0; i < Event.Method.ParameterNames.Count; i++)
            {
                buff.Append(Tabs.ToString()).Append("\t<Parameter ");
                buff.Append("name").Append("=\"").Append(Event.Method.ParameterNames[i]).Append("\" ");
                buff.Append("type").Append("=\"").Append(Event.Method.ParameterTypeNames[i]).Append("\" ");
                buff.Append("value").Append("=\"").Append(parameters[i].Value).Append("\" ");
                buff.Append(">\n");
            }
            buff.Append("\n");
            Writer.WriteLine(buff.ToString());
            Tabs.Append("\t");
        }

        public void MethodExitEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
            ResolvedMethodExitEvent Event = new ResolvedMethodExitEvent(Process, ev as MethodExitEvent);
            Writer.Write(Tabs.ToString());
            Writer.WriteLine("</Call>");
            Tabs.Remove(Tabs.Length-1, 1);
        }

        #region ignored events
        public void CallSiteEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionThrownEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionSearchFunctionEnterEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionSearchFunctionExitEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionSearchFilterEnterEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionSearchFilterExitEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionSearchCatchFoundEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionUnwindFunctionEnterEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionUnwindFunctionExitEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionUnwindFinallyEnterEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionUnwindFinallyExitEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionCatchEnterEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }

        public void ExceptionCatchExitEvent(Microsoft.VisualStudio.IntelliTrace.IntelliTraceEvent ev)
        {
        }
        #endregion

        public void Dispose()
        {
            Writer.WriteLine("</Calls>");
            Writer.Flush();
            Writer.Dispose();
            Writer.Close();
        }
    }
}
